package net.xdclass.product.service.impl;

import com.alibaba.fastjson.JSON;
import com.google.gson.Gson;
import io.jsonwebtoken.lang.Collections;
import lombok.extern.slf4j.Slf4j;
import net.xdclass.common.JsonData;
import net.xdclass.common.constant.Cons;
import net.xdclass.common.enums.BizCodeEnum;
import net.xdclass.common.exception.BizException;
import net.xdclass.common.model.LoginUser;
import net.xdclass.local.ThreadLocal;
import net.xdclass.product.model.vo.CartItemVO;
import net.xdclass.product.model.vo.CartVO;
import net.xdclass.product.model.vo.ProductVO;
import net.xdclass.product.request.CartItemRequest;
import net.xdclass.product.service.CartService;
import net.xdclass.product.service.ProductService;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.BoundHashOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @author yaya
 */
@Slf4j
@Service
public class CartServiceImpl implements CartService {

    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private ProductService productService;

    /**
     * 添加商品到购物车【cache】
     * @param cartItemRequest
     */
    @Override
    public void addCart(CartItemRequest cartItemRequest) {
        checkParam(cartItemRequest);
        Long productId = cartItemRequest.getProductId();
        Integer count = cartItemRequest.getCount();
        BoundHashOperations<String, Object, Object> myCart = getCartOps();
        Object cachePro = myCart.get(productId);
        String result = null;
        if (ObjectUtils.isNotEmpty(cachePro)){
            result = cachePro.toString();
        }
        Gson gson = new Gson();
        if (StringUtils.isEmpty(result)){
            // 新增购物项
            CartItemVO cartItem = new CartItemVO();
            ProductVO product = productService.selectProductById(productId);
            if (product == null || product.getId() == null) {
                throw new BizException(BizCodeEnum.PRODUCT_NOT_EXIST);
            }
            cartItem.setAmount(product.getPrice()); // TODO 统一一下属性
            cartItem.setProductId(productId);
            cartItem.setProductImg(product.getCoverImg());
            cartItem.setProductTitle(product.getTitle());
            cartItem.setCount(count);
            myCart.put(productId, gson.toJson(cartItem));
        }else {
            // 新增购买数量
            CartItemVO cartItem = gson.fromJson(result, CartItemVO.class);
            cartItem.setCount(cartItem.getCount() + count);

            myCart.put(productId, gson.toJson(cartItem));
        }
    }

    /**
     * 查询商品最新价格
     *
     * @param productIds
     * @return
     */
    @Override
    public List<CartItemVO> confirmOrderItem(List<Long> productIds) {
        if (CollectionUtils.isEmpty(productIds)){
            return java.util.Collections.emptyList();
        }
        List<CartItemVO> cartItemVOS = buildCartItem(true);
        // 返回提交的商品id && 将提交的id从购物车中删除
        List<CartItemVO> res = cartItemVOS.stream().filter(item -> {
            if (productIds.contains(item.getProductId())){
                // TODO 放到mq中去延迟清空
                deleteItem(item.getProductId());
                return true;
            }
            return false;
        }).collect(Collectors.toList());
        return res;
    }

    /**
     * 更新购物车
     *
     * @param cartItem
     * @return
     */
    @Override
    public boolean updateCartItem(CartItemRequest cartItem) {
        checkParam(cartItem);
        BoundHashOperations<String, Object, Object> myCart = getCartOps();
        Object obj = myCart.get(cartItem.getProductId());
        if (obj == null){
            throw new BizException(BizCodeEnum.PRODUCT_NOT_EXIST);
        }
        if (obj instanceof CartItemVO){
            CartItemVO cartItemVO = (CartItemVO) obj;
            cartItemVO.setCount(cartItem.getCount());
            myCart.put(cartItem.getProductId(), JSON.toJSONString(cartItemVO));
        }
        return true;
    }

    /**
     * 删除购物项
     *
     * @param productId
     * @return
     */
    @Override
    public boolean deleteItem(Long productId) {
        BoundHashOperations<String, Object, Object> myCart = getCartOps();
        Long delete = myCart.delete(productId);
        return delete > 0;
    }

    /**
     * 查询我的购物车
     *
     * @return
     */
    @Override
    public CartVO getMyCart() {
        List<CartItemVO> lists = buildCartItem(false);
        CartVO cart = new CartVO();
        cart.setCartItems(lists);
        return cart;
    }

    /**
     * 获取最新购物项
     * @param latestPrice 是否查询最新价格
     * @return
     */
    private List<CartItemVO> buildCartItem(boolean latestPrice) {
        BoundHashOperations<String, Object, Object> myCart = getCartOps();
        // 全部购物项
        List<CartItemVO> cartItemList = new ArrayList<>();
        List<Object> itemList = myCart.values();
        if (Collections.isEmpty(itemList)){
            return cartItemList;
        }
        List<Long> productIds = new ArrayList<>();
        for (Object item : itemList) {
            CartItemVO cartItem = JSON.parseObject(item.toString(), CartItemVO.class);
            cartItemList.add(cartItem);
            productIds.add(cartItem.getProductId());
        }
        // 查询商品最新价格
        if (latestPrice){
            buildProductLatestPrice(cartItemList, productIds);
        }
        return cartItemList;
    }

    /**
     * 设置商品最新价格
     */
    private void buildProductLatestPrice(List<CartItemVO> cartItems, List<Long> productIds) {
        List<ProductVO> products = productService.selectProductByIds(productIds);
        Map<Long, ProductVO> collect =
                products.stream().collect(Collectors.toMap(ProductVO::getId, Function.identity()));
        for (CartItemVO cartItem : cartItems) {
            ProductVO product = collect.get(cartItem.getProductId());
            cartItem.setAmount(product.getPrice());
            cartItem.setProductTitle(product.getTitle());
            cartItem.setProductImg(product.getCoverImg());
        }
    }

    /**
     * 清空购物车
     *
     * @return
     */
    @Override
    public boolean clear() {
        String cartKey = getCartKey();
        return Boolean.TRUE.equals(redisTemplate.delete(cartKey));
    }

    private void checkParam(CartItemRequest cartItemRequest) {
        if (ObjectUtils.isEmpty(cartItemRequest)
                || ObjectUtils.isEmpty(cartItemRequest.getCount())
                || ObjectUtils.isEmpty(cartItemRequest.getProductId())
                || cartItemRequest.getCount() <= 0
                || cartItemRequest.getProductId() <= 0){
            throw new BizException(BizCodeEnum.CART_PARAM_ERROR);
        }
    }

    /**
     * 查询我的购物车
     *
     * @return
     */
    private BoundHashOperations<String, Object, Object> getCartOps(){
        String cartKey = getCartKey();
        return redisTemplate.boundHashOps(cartKey);
    }

    /**
     * 获取用户购物车缓存key
     * @return
     */
    private String getCartKey(){
        LoginUser loginUser = ThreadLocal.getLoginUser();
        String cacheKey = String.format(Cons.CART_CACHE_KEY, loginUser.getId());
        return cacheKey;
    }
}
